package top.jolyoulu.codegenweb.service.bll.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.jolyoulu.codegenweb.entity.bo.form.GenTemplateFileFormBO;
import top.jolyoulu.codegenweb.entity.bo.form.GenTemplateGroupFormBO;
import top.jolyoulu.codegenweb.entity.po.FileData;
import top.jolyoulu.codegenweb.entity.po.GenTemplateFile;
import top.jolyoulu.codegenweb.entity.po.GenTemplateGroup;
import top.jolyoulu.codegenweb.entity.vo.GenTemplateFileVO;
import top.jolyoulu.codegenweb.entity.vo.GenTemplateGroupVO;
import top.jolyoulu.codegenweb.service.bll.ApiFileDataService;
import top.jolyoulu.codegenweb.service.bll.ApiGenTemplateService;
import top.jolyoulu.codegenweb.service.dal.FileDataService;
import top.jolyoulu.codegenweb.service.dal.GenTemplateFileService;
import top.jolyoulu.codegenweb.service.dal.GenTemplateGroupService;
import top.jolyoulu.corecommon.utils.encryption.MD5Utils;
import top.jolyoulu.webcommon.enums.GlobalExpType;
import top.jolyoulu.webcommon.excption.GlobalException;
import top.jolyoulu.webcommon.utils.ResponseUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: JolyouLu
 * @Date: 2023/4/8 14:44
 * @Description
 */
@Slf4j
@Service
public class ApiGenTemplateServiceImpl implements ApiGenTemplateService {

    @Autowired
    private GenTemplateGroupService genTemplateGroupService;

    @Autowired
    private GenTemplateFileService genTemplateFileService;

    @Autowired
    private ApiFileDataService apiFileDataService;

    @Autowired
    private FileDataService fileDataService;

    @Override
    public List<GenTemplateGroupVO> list() {
        ArrayList<GenTemplateGroupVO> res = new ArrayList<>();
        List<GenTemplateGroup> groups = genTemplateGroupService.list();
        for (GenTemplateGroup item : groups) {
            GenTemplateGroupVO vo = new GenTemplateGroupVO();
            vo.setId(item.getId());
            vo.setGroupName(item.getGroupName());
            List<GenTemplateFile> fileList = genTemplateFileService.selectByGroupId(item.getId());
            vo.setFileList(fileList.stream().map(m -> {
                GenTemplateFileVO fileVO = new GenTemplateFileVO();
                fileVO.setId(m.getId());
                fileVO.setTemplateName(m.getTemplateName());
                fileVO.setGenFileName(m.getGenFileName());
                return fileVO;
            }).collect(Collectors.toList()));
            res.add(vo);
        }
        return res;
    }

    @Override
    @Transactional
    public void groupAdd(GenTemplateGroupFormBO bo) {
        GenTemplateGroup genTemplateGroup = new GenTemplateGroup();
        BeanUtils.copyProperties(bo, genTemplateGroup);
        genTemplateGroupService.save(genTemplateGroup);
    }

    @Override
    @Transactional
    public void groupEdit(GenTemplateGroupFormBO bo) {
        GenTemplateGroup genTemplateGroup = new GenTemplateGroup();
        BeanUtils.copyProperties(bo, genTemplateGroup);
        genTemplateGroupService.updateById(genTemplateGroup);
    }

    @Override
    @Transactional
    public void groupDel(List<String> ids) {
        for (String id : ids) {
            //删除文件
            apiFileDataService.removeByGroupId(id);
            //删除模板文件
            genTemplateFileService.removeByGroupId(id);
            //删除数据
            genTemplateGroupService.removeById(id);
        }
    }

    @Override
    public List<GenTemplateFileVO> groupFileList(String groupId) {
        List<GenTemplateFile> templateFiles = genTemplateFileService.list(new LambdaQueryWrapper<GenTemplateFile>()
                .eq(GenTemplateFile::getGroupId, groupId));
        return templateFiles.stream().map(GenTemplateFileVO::new).collect(Collectors.toList());
    }

    @Override
    public GenTemplateFileVO fileById(String id) {
        GenTemplateFile templateFile = genTemplateFileService.getById(id);
        return new GenTemplateFileVO(templateFile);
    }

    @Override
    @Transactional
    public void fileAdd(GenTemplateFileFormBO bo) {
        //保存文件
        try {
            GenTemplateFile templateFile = new GenTemplateFile();
            if (Objects.nonNull(bo.getFile())) {
                byte[] bytes = bo.getFile().getBytes();
                String md5 = MD5Utils.encode(bytes);
                FileData fileData = new FileData();
                fileData.setFileMd5(md5);
                if (StringUtils.isNotBlank(bo.getGenFileName())) {
                    String genFileName = bo.getGenFileName();
                    fileData.setFileName(genFileName.split("\\.")[0]);
                }
                fileData.setFileExtension("ftl");
                fileData.setFileSize(bo.getFile().getSize());
                fileData.setFileByte(bytes);
                if (!fileDataService.save(fileData)) {
                    throw new GlobalException(GlobalExpType.UNKNOWN_ERROR);
                }
                templateFile.setFileId(fileData.getId());
            }
            BeanUtils.copyProperties(bo, templateFile);
            genTemplateFileService.save(templateFile);
        } catch (IOException e) {
            log.error("", e);
        }
    }

    @Override
    @Transactional
    public void fileEdit(GenTemplateFileFormBO bo) {
        //保存文件
        try {
            GenTemplateFile tempFile = genTemplateFileService.getById(bo.getId());
            if (Objects.isNull(tempFile)) {
                throw new GlobalException(GlobalExpType.PARAM_ERROR);
            }
            GenTemplateFile templateFile = new GenTemplateFile();
            if (Objects.nonNull(bo.getFile())) {
                byte[] bytes = bo.getFile().getBytes();
                String md5 = MD5Utils.encode(bytes);
                FileData fileData = new FileData();
                fileData.setId(tempFile.getFileId());
                fileData.setFileMd5(md5);
                if (StringUtils.isNotBlank(bo.getGenFileName())) {
                    String genFileName = bo.getGenFileName();
                    fileData.setFileName(genFileName.split("\\.")[0]);
                }
                fileData.setFileSize(bo.getFile().getSize());
                fileData.setFileByte(bytes);
                if (!fileDataService.updateById(fileData)) {
                    throw new GlobalException(GlobalExpType.UNKNOWN_ERROR);
                }
                templateFile.setFileId(fileData.getId());
            }
            BeanUtils.copyProperties(bo, templateFile);
            genTemplateFileService.updateById(templateFile);
        } catch (IOException e) {
            log.error("", e);
        }
    }

    @Override
    @Transactional
    public void fileDel(List<String> ids) {
        for (String id : ids) {
            GenTemplateFile tempFile = genTemplateFileService.getById(id);
            if (Objects.isNull(tempFile)) {
                continue;
            }
            fileDataService.removeById(tempFile.getFileId());
            genTemplateFileService.removeById(id);
        }
    }

    @Override
    public void fileDownload(String id, HttpServletResponse response) {
        try {
            GenTemplateFile tempFile = genTemplateFileService.getById(id);
            if (Objects.isNull(tempFile)) {
                throw new GlobalException(GlobalExpType.PARAM_ERROR);
            }
            FileData fileData = fileDataService.getById(tempFile.getFileId());
            ResponseUtils.outStream(response, fileData.getFileByte());
        } catch (IOException e) {
            log.error("", e);
        }
    }
}
